package com.chuanyun.wechatcheckin.service;

import com.chuanyun.wechatcheckin.config.H3yunConfig;
import com.chuanyun.wechatcheckin.model.h3yun.BizDataParameters;
import com.chuanyun.wechatcheckin.model.h3yun.H3yunRequest;
import com.chuanyun.wechatcheckin.model.h3yun.H3yunResponse;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 氚云API服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class H3yunApiService {
    
    private final H3yunConfig h3yunConfig;
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final Gson gson = new Gson();
    

    
    /**
     * 批量插入用户ID数据
     */
    public void batchInsertUserIds(List<String> userIds) throws Exception {
        if (!StringUtils.hasText(h3yunConfig.getEngineCode()) || 
            !StringUtils.hasText(h3yunConfig.getEngineSecret())) {
            log.warn("氚云配置为空，跳过插入用户数据操作");
            return;
        }
        
        if (userIds == null || userIds.isEmpty()) {
            log.warn("用户ID列表为空，跳过插入操作");
            return;
        }
        
        log.info("开始批量插入用户ID数据，数量: {}", userIds.size());
        
        // 转换为氚云需要的JSON字符串数组格式
        List<String> bizObjectArray = userIds.stream()
                .map(userId -> {
                    Map<String, Object> data = new HashMap<>();
                    data.put("UserId", userId);
                    // 可以根据需要添加其他必要字段，如CreatedBy, OwnerId等
                    return gson.toJson(data);
                })
                .collect(Collectors.toList());
        
        // 使用Map方式构建请求参数
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("ActionName", "CreateBizObjects");
        paramMap.put("SchemaCode", h3yunConfig.getUserTable().getSchemaCode());
        paramMap.put("BizObjectArray", bizObjectArray);
        paramMap.put("IsSubmit", "true");  // 创建生效数据
        
        // 身份认证参数
        Map<String, String> headers = new HashMap<>();
        headers.put("EngineCode", h3yunConfig.getEngineCode());
        headers.put("EngineSecret", h3yunConfig.getEngineSecret());
        
        H3yunResponse<Object> response = callH3yunApiWithMap(paramMap, headers, new TypeReference<H3yunResponse<Object>>() {});
        
        if (!response.isSuccess()) {
            log.error("批量插入用户数据失败: {}", response.getErrorMessage());
            throw new RuntimeException(String.format("批量插入用户数据失败: %s", response.getErrorMessage()));
        }
        
        log.info("氚云用户ID数据插入完成，数量: {}", userIds.size());
    }
    
    /**
     * 批量创建业务对象（支持复杂数据结构）
     * @param schemaCode 表单编码
     * @param bizObjectDataList 业务对象数据列表
     * @param isSubmit 是否提交（true为生效数据，false为草稿数据）
     * @throws Exception 创建异常
     */
    public void batchCreateBizObjects(String schemaCode, List<Map<String, Object>> bizObjectDataList, boolean isSubmit) throws Exception {
        if (!StringUtils.hasText(h3yunConfig.getEngineCode()) || 
            !StringUtils.hasText(h3yunConfig.getEngineSecret())) {
            log.warn("氚云配置为空，跳过创建业务对象操作");
            return;
        }
        
        if (bizObjectDataList == null || bizObjectDataList.isEmpty()) {
            log.warn("业务对象数据列表为空，跳过创建操作");
            return;
        }
        
        if (!StringUtils.hasText(schemaCode)) {
            throw new RuntimeException("表单编码不能为空");
        }
        
        log.info("开始批量创建业务对象，表单编码: {}, 数量: {}", schemaCode, bizObjectDataList.size());
        
        // 转换为氚云需要的JSON字符串数组格式
        List<String> bizObjectArray = bizObjectDataList.stream()
                .map(data -> gson.toJson(data))
                .collect(Collectors.toList());
        
        // 使用Map方式构建请求参数
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("ActionName", "CreateBizObjects");
        paramMap.put("SchemaCode", schemaCode);
        paramMap.put("BizObjectArray", bizObjectArray);
        paramMap.put("IsSubmit", String.valueOf(isSubmit));
        
        // 身份认证参数
        Map<String, String> headers = new HashMap<>();
        headers.put("EngineCode", h3yunConfig.getEngineCode());
        headers.put("EngineSecret", h3yunConfig.getEngineSecret());
        
        H3yunResponse<Object> response = callH3yunApiWithMap(paramMap, headers, new TypeReference<H3yunResponse<Object>>() {});
        
        if (!response.isSuccess()) {
            log.error("批量创建业务对象失败: {}", response.getErrorMessage());
            throw new RuntimeException(String.format("批量创建业务对象失败: %s", response.getErrorMessage()));
        }
        
        log.info("氚云业务对象创建完成，数量: {}", bizObjectDataList.size());
    }
    
    /**
     * 创建单个业务对象
     */
    public String createBizObject(String schemaCode, Map<String, Object> bizObjectData, boolean isSubmit) throws Exception {
        if (!StringUtils.hasText(h3yunConfig.getEngineCode()) || 
            !StringUtils.hasText(h3yunConfig.getEngineSecret())) {
            log.warn("氚云配置为空，跳过创建业务对象操作");
            return null;
        }
        
        if (bizObjectData == null || bizObjectData.isEmpty()) {
            log.warn("业务对象数据为空，跳过创建操作");
            return null;
        }
        
        if (!StringUtils.hasText(schemaCode)) {
            throw new RuntimeException("表单编码不能为空");
        }
        
        log.info("开始创建单个业务对象，表单编码: {}", schemaCode);
        
        // 使用Map方式构建请求参数
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("ActionName", "CreateBizObject");
        paramMap.put("SchemaCode", schemaCode);
        paramMap.put("BizObject", gson.toJson(bizObjectData));
        paramMap.put("IsSubmit", String.valueOf(isSubmit));
        
        // 身份认证参数
        Map<String, String> headers = new HashMap<>();
        headers.put("EngineCode", h3yunConfig.getEngineCode());
        headers.put("EngineSecret", h3yunConfig.getEngineSecret());
        
        H3yunResponse<Object> response = callH3yunApiWithMap(paramMap, headers, new TypeReference<H3yunResponse<Object>>() {});
        
        if (!response.isSuccess()) {
            log.error("创建业务对象失败: {}", response.getErrorMessage());
            throw new RuntimeException(String.format("创建业务对象失败: %s", response.getErrorMessage()));
        }
        
        // 解析返回的业务对象ID
        String bizObjectId = null;
        if (response.getReturnData() != null) {
            Object returnData = response.getReturnData();
            if (returnData instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> dataMap = (Map<String, Object>) returnData;
                bizObjectId = (String) dataMap.get("BizObjectId");
            } else {
                bizObjectId = returnData.toString();
            }
        }
        
        log.info("氚云业务对象创建完成，ID: {}", bizObjectId);
        return bizObjectId;
    }
    
    /**
     * 更新单个业务对象
     */
    public void updateBizObject(String schemaCode, String bizObjectId, Map<String, Object> bizObjectData, boolean isSubmit) throws Exception {
        if (!StringUtils.hasText(h3yunConfig.getEngineCode()) || 
            !StringUtils.hasText(h3yunConfig.getEngineSecret())) {
            log.warn("氚云配置为空，跳过更新业务对象操作");
            return;
        }
        
        if (bizObjectData == null || bizObjectData.isEmpty()) {
            log.warn("业务对象数据为空，跳过更新操作");
            return;
        }
        
        if (!StringUtils.hasText(schemaCode)) {
            throw new RuntimeException("表单编码不能为空");
        }
        
        if (!StringUtils.hasText(bizObjectId)) {
            throw new RuntimeException("业务对象ID不能为空");
        }
        
        log.info("更新氚云业务对象 - ID: {}", bizObjectId);
        
        // 使用Map方式构建请求参数
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("ActionName", "UpdateBizObject");
        paramMap.put("SchemaCode", schemaCode);
        paramMap.put("BizObjectId", bizObjectId);
        paramMap.put("BizObject", gson.toJson(bizObjectData));
        paramMap.put("IsSubmit", String.valueOf(isSubmit));
        
        // 身份认证参数
        Map<String, String> headers = new HashMap<>();
        headers.put("EngineCode", h3yunConfig.getEngineCode());
        headers.put("EngineSecret", h3yunConfig.getEngineSecret());
        
        H3yunResponse<Object> response = callH3yunApiWithMap(paramMap, headers, new TypeReference<H3yunResponse<Object>>() {});
        
        if (!response.isSuccess()) {
            log.error("更新业务对象失败: {}", response.getErrorMessage());
            throw new RuntimeException(String.format("更新业务对象失败: %s", response.getErrorMessage()));
        }

    }
    
    /**
     * 调用氚云API（使用Map和Header方式）
     */
    private <T> T callH3yunApiWithMap(Map<String, Object> paramMap, Map<String, String> headers, TypeReference<T> responseType) throws Exception {
        String url = "https://www.h3yun.com/OpenApi/Invoke";
        
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            
            // 设置请求头
            httpPost.setHeader("Content-Type", "application/json");
            for (Map.Entry<String, String> header : headers.entrySet()) {
                httpPost.setHeader(header.getKey(), header.getValue());
            }
            
            // 设置请求体
            String jsonBody = gson.toJson(paramMap);
            httpPost.setEntity(new StringEntity(jsonBody, ContentType.APPLICATION_JSON));
            
            return httpClient.execute(httpPost, response -> {
                int statusCode = response.getCode();
                String responseBody = EntityUtils.toString(response.getEntity());
                
                if (statusCode != 200) {
                    log.error("氚云API调用失败，状态码: {}", statusCode);
                    throw new RuntimeException(String.format("氚云API调用失败，状态码: %d", statusCode));
                }
                
                // 检查响应是否为HTML（通常表示错误页面）
                if (responseBody.trim().startsWith("<")) {
                    log.error("氚云API返回HTML错误页面");
                    throw new RuntimeException("氚云API返回HTML错误页面");
                }
                
                return objectMapper.readValue(responseBody, responseType);
            });
        }
    }
    
    /**
     * 批量查询业务数据
     * @param schemaCode 业务对象编码（必填）
     * @param fromRowNum 起始行号
     * @param toRowNum 结束行号
     * @param returnItems 返回字段列表，为空则返回所有字段
     * @return 查询结果
     * @throws Exception 查询异常
     */
    public H3yunResponse<Object> queryBizData(String schemaCode, int fromRowNum, int toRowNum, List<String> returnItems) throws Exception {
        return queryBizData(schemaCode, fromRowNum, toRowNum, returnItems, false);
    }
    
    /**
     * 批量查询业务数据（支持自定义查询条件）
     * @param schemaCode 业务对象编码（必填）
     * @param fromRowNum 起始行号
     * @param toRowNum 结束行号
     * @param returnItems 返回字段列表，为空则返回所有字段
     * @param customMatchers 自定义查询条件列表
     * @return 查询结果
     * @throws Exception 查询异常
     */
    public H3yunResponse<Object> queryBizDataWithConditions(String schemaCode, int fromRowNum, int toRowNum, 
                                                           List<String> returnItems, List<Map<String, Object>> customMatchers) throws Exception {
        if (!StringUtils.hasText(h3yunConfig.getEngineCode()) || 
            !StringUtils.hasText(h3yunConfig.getEngineSecret())) {
            log.warn("氚云配置为空，跳过查询业务数据操作");
            throw new RuntimeException("氚云配置为空");
        }
        
        if (!StringUtils.hasText(schemaCode)) {
            throw new RuntimeException("业务对象编码不能为空");
        }
        
        log.info("查询氚云业务数据: SchemaCode={}, 行号范围: {}-{}", schemaCode, fromRowNum, toRowNum);
        
        // 构建Filter对象（按照API文档格式）
        Map<String, Object> filter = new HashMap<>();
        filter.put("FromRowNum", fromRowNum);
        filter.put("RequireCount", false);
        filter.put("ReturnItems", returnItems != null ? returnItems : new ArrayList<>());
        filter.put("SortByCollection", new ArrayList<>());
        filter.put("ToRowNum", toRowNum);
        
        // 构建Matcher对象
        Map<String, Object> matcher = new HashMap<>();
        matcher.put("Type", "And");
        matcher.put("Matchers", customMatchers != null ? customMatchers : new ArrayList<>());
        filter.put("Matcher", matcher);
        
        // 使用Map方式构建请求参数（完全按照API文档示例）
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("ActionName", "LoadBizObjects");
        paramMap.put("SchemaCode", schemaCode);
        paramMap.put("Filter", gson.toJson(filter));  // Filter作为JSON字符串
        
        // 身份认证参数
        Map<String, String> headers = new HashMap<>();
        headers.put("EngineCode", h3yunConfig.getEngineCode());
        headers.put("EngineSecret", h3yunConfig.getEngineSecret());
        
        log.debug("氚云查询请求参数: {}", gson.toJson(paramMap));
        log.debug("氚云查询Filter内容: {}", gson.toJson(filter));
        
        H3yunResponse<Object> response = callH3yunApiWithMap(paramMap, headers, new TypeReference<H3yunResponse<Object>>() {});
        
        if (!response.isSuccess()) {
            log.error("查询业务数据失败: {}", response.getErrorMessage());
            throw new RuntimeException(String.format("查询业务数据失败: %s", response.getErrorMessage()));
        }
        
        log.info("成功查询氚云业务数据");
        return response;
    }
    
    /**
     * 批量查询业务数据
     * @param schemaCode 业务对象编码（必填）
     * @param fromRowNum 起始行号
     * @param toRowNum 结束行号
     * @param returnItems 返回字段列表，为空则返回所有字段
     * @param requireCount 是否需要返回总数
     * @return 查询结果
     * @throws Exception 查询异常
     */
    public H3yunResponse<Object> queryBizData(String schemaCode, int fromRowNum, int toRowNum, List<String> returnItems, boolean requireCount) throws Exception {
        return queryBizDataWithConditions(schemaCode, fromRowNum, toRowNum, returnItems, null);
    }
    
    /**
     * 分页查询业务数据
     * @param schemaCode 业务对象编码
     * @param pageSize 每页大小
     * @param pageNum 页码（从1开始）
     * @param returnItems 返回字段列表
     * @return 查询结果
     * @throws Exception 查询异常
     */
    public H3yunResponse<Object> queryBizDataByPage(String schemaCode, int pageSize, int pageNum, List<String> returnItems) throws Exception {
        int fromRowNum = (pageNum - 1) * pageSize;
        int toRowNum = fromRowNum + pageSize;
        return queryBizData(schemaCode, fromRowNum, toRowNum, returnItems);
    }
    
    /**
     * 根据业务对象ID查询单条数据
     * @param schemaCode 表单编码
     * @param bizObjectId 业务对象ID
     * @return 查询结果
     * @throws Exception 查询异常
     */
    public H3yunResponse<Object> findDataById(String schemaCode, String bizObjectId) throws Exception {
        if (!StringUtils.hasText(h3yunConfig.getEngineCode()) || 
            !StringUtils.hasText(h3yunConfig.getEngineSecret())) {
            log.warn("氚云配置为空，跳过查询数据操作");
            throw new RuntimeException("氚云配置为空");
        }
        
        if (!StringUtils.hasText(schemaCode) || !StringUtils.hasText(bizObjectId)) {
            throw new RuntimeException("表单编码和业务对象ID不能为空");
        }
        
        log.info("开始根据ID查询氚云数据，SchemaCode: {}, BizObjectId: {}", schemaCode, bizObjectId);
        
        // 使用Map方式构建请求参数
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("ActionName", "LoadBizObject");
        paramMap.put("SchemaCode", schemaCode);
        paramMap.put("BizObjectId", bizObjectId);
        
        // 身份认证参数
        Map<String, String> headers = new HashMap<>();
        headers.put("EngineCode", h3yunConfig.getEngineCode());
        headers.put("EngineSecret", h3yunConfig.getEngineSecret());
        
        H3yunResponse<Object> response = callH3yunApiWithMap(paramMap, headers, new TypeReference<H3yunResponse<Object>>() {});
        
        if (!response.isSuccess()) {
            throw new RuntimeException(String.format("根据ID查询数据失败: %s", response.getErrorMessage()));
        }
        
        log.info("成功根据ID查询氚云数据");
        return response;
    }
    
    /**
     * 解析氚云API返回的数据
     * @param returnData 返回的数据对象
     * @return 解析后的数据列表
     */
    @SuppressWarnings("unchecked")
    private List<Map<String, Object>> parseResponseData(Object returnData) {
        if (returnData == null) {
            return new ArrayList<>();
        }
        
        log.debug("氚云返回数据类型: {}", returnData.getClass().getSimpleName());
        
        if (returnData instanceof List) {
            // 如果返回的是List，直接转换
            List<Map<String, Object>> dataList = (List<Map<String, Object>>) returnData;
            log.debug("直接解析List，数据条数: {}", dataList.size());
            return dataList;
        } else if (returnData instanceof Map) {
            // 如果返回的是Map，可能包含BizObject字段（单个对象）或BizObjectArray字段（多个对象）
            Map<String, Object> dataMap = (Map<String, Object>) returnData;
            log.debug("返回Map结构，包含字段: {}", dataMap.keySet());
            
            // 首先检查是否是单个BizObject（根据新的返回格式）
            Object bizObject = dataMap.get("BizObject");
            if (bizObject instanceof Map) {
                // 单个业务对象，包装成List返回
                List<Map<String, Object>> dataList = new ArrayList<>();
                dataList.add((Map<String, Object>) bizObject);
                log.debug("解析单个BizObject，数据条数: 1");
                return dataList;
            }
            
            // 尝试多种可能的数组字段名
            Object bizObjectArray = dataMap.get("BizObjectArray");
            if (bizObjectArray == null) {
                bizObjectArray = dataMap.get("Data");
            }
            if (bizObjectArray == null) {
                bizObjectArray = dataMap.get("Items");
            }
            if (bizObjectArray == null) {
                bizObjectArray = dataMap.get("List");
            }
            if (bizObjectArray == null) {
                // 如果没有找到预期的字段，尝试找到第一个List类型的值
                for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
                    if (entry.getValue() instanceof List) {
                        bizObjectArray = entry.getValue();
                        log.debug("找到List类型字段: {}", entry.getKey());
                        break;
                    }
                }
            }
            
            if (bizObjectArray instanceof List) {
                List<Map<String, Object>> dataList = (List<Map<String, Object>>) bizObjectArray;
                log.debug("从Map中解析List，数据条数: {}", dataList.size());
                return dataList;
            } else if (bizObjectArray != null) {
                log.warn("氚云返回数据格式异常，BizObjectArray不是List类型: {}, 类型: {}", 
                        bizObjectArray, bizObjectArray.getClass().getSimpleName());
            } else {
                log.warn("氚云返回Map中未找到数据数组字段，Map内容: {}", dataMap);
            }
        } else {
            log.warn("氚云返回数据格式异常，不是List或Map类型: {}", returnData.getClass());
        }
        
        return new ArrayList<>();
    }
    
    /**
     * 批量删除指定的用户ID
     * @param userIds 要删除的用户ID列表
     * @throws Exception 删除异常
     */
    public void batchDeleteUserIds(List<String> userIds) throws Exception {
        if (!StringUtils.hasText(h3yunConfig.getEngineCode()) || 
            !StringUtils.hasText(h3yunConfig.getEngineSecret())) {
            log.warn("氚云配置为空，跳过删除用户数据操作");
            return;
        }
        
        if (userIds == null || userIds.isEmpty()) {
            log.warn("要删除的用户ID列表为空，跳过删除操作");
            return;
        }
        
        log.info("开始批量删除用户ID数据，数量: {}", userIds.size());
        
        // 构建删除条件：UserId在指定列表中
        Map<String, Object> matcher = new HashMap<>();
        matcher.put("Type", "And");
        
        List<Map<String, Object>> matchers = new ArrayList<>();
        Map<String, Object> userIdMatcher = new HashMap<>();
        userIdMatcher.put("PropertyCode", "UserId");
        userIdMatcher.put("PropertyType", 0); // 字符串类型
        userIdMatcher.put("MatchType", 8); // In操作符
        userIdMatcher.put("Value", userIds);
        matchers.add(userIdMatcher);
        
        matcher.put("Matchers", matchers);
        
        // 构建Filter对象
        Map<String, Object> filter = new HashMap<>();
        filter.put("Matcher", matcher);
        
        // 使用Map方式构建请求参数
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("ActionName", "RemoveBizObject");
        paramMap.put("SchemaCode", h3yunConfig.getUserTable().getSchemaCode());
        paramMap.put("BizDataArray", null);
        paramMap.put("Filter", gson.toJson(filter));
        
        // 身份认证参数
        Map<String, String> headers = new HashMap<>();
        headers.put("EngineCode", h3yunConfig.getEngineCode());
        headers.put("EngineSecret", h3yunConfig.getEngineSecret());
        
        H3yunResponse<Object> response = callH3yunApiWithMap(paramMap, headers, new TypeReference<H3yunResponse<Object>>() {});
        
        if (!response.isSuccess()) {
            log.error("批量删除用户数据失败: {}", response.getErrorMessage());
            throw new RuntimeException(String.format("批量删除用户数据失败: %s", response.getErrorMessage()));
        }
        
        log.info("氚云用户ID数据删除完成，数量: {}", userIds.size());
    }
}